﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.HomeServer.Controls;
using Serviio.API;

namespace Serviio.WHS
{
    public partial class StatusTabControl : UserControl
    {
        private static readonly LogFacade log = LogFacade.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public StatusTabControl()
        {
            InitializeComponent();
        }

        private ServiioConnection conn = null;

        public void Initialize(ServiioConnection connection)
        {
            try
            {
                if (this.conn != null)
                    return;

                log.Info("Initializing...");

                this.conn = connection;
                PopulateDevices();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void RefreshDevices()
        {
            try
            {
                if (conn == null)
                    return;

                conn.Status.Refresh();

                PopulateDevices();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void PopulateDevices()
        {
            try
            {
                if (conn == null)
                    return;

                if (conn.Status.ServerStatus == ServiioStatus.ServerStates.Started)
                {
                    buttonStart.Checked = true;
                    buttonStart.Image = Properties.Resources.Green16;
                    buttonStart.Text = "Enabled";
                }
                else
                {
                    buttonStart.Checked = false;
                    buttonStart.Image = Properties.Resources.Red16;
                    buttonStart.Text = "Disabled";
                }

                listViewDevices.Items.Clear();

                foreach (ServiioDevice device in conn.Status.Devices)
                {
                    ListViewItem deviceItem = new ListViewItem(device.Name);
                    deviceItem.ImageKey = "GENERIC";
                    deviceItem.SubItems.Add(device.HostName);
                    deviceItem.SubItems.Add(device.IpAddress);
                    deviceItem.SubItems.Add(device.ProfileName);

                    FancyListView.ImageSubItem deviceStatusItem = new FancyListView.ImageSubItem();
                    deviceStatusItem.Text = device.Status;
                    deviceStatusItem.ImageKey = device.Status;
                    deviceItem.SubItems.Add(deviceStatusItem);

                    listViewDevices.Items.Add(deviceItem);
                    device.OnHostUpdated += HostNameUpdated;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private delegate void HostNameUpdatedDelegate(ServiioDevice device);
        private void HostNameUpdated(ServiioDevice device)
        {
            try
            {
                if (listViewDevices.InvokeRequired)
                {
                    this.Invoke(new HostNameUpdatedDelegate(HostNameUpdated), device);
                    return;
                }

                foreach (ListViewItem deviceItem in listViewDevices.Items)
                {
                    if (device.IpAddress.Equals(deviceItem.SubItems[2].Text))
                    {
                        deviceItem.SubItems[1].Text = device.HostName;
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void EditItem(ListViewItem item)
        {
            try
            {
                ServiioDevice selectedDevice = null;
                String ipAddress = item.SubItems[2].Text;
                foreach (ServiioDevice device in conn.Status.Devices)
                {
                    if (device.IpAddress.Equals(ipAddress))
                        selectedDevice = device;
                }

                if (selectedDevice != null)
                {
                    DeviceDetailsForm dialog = new DeviceDetailsForm();
                    if (dialog.Edit(conn, selectedDevice))
                    {
                        conn.Status.Update();
                        RefreshDevices();
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void RemoveItem(ListViewItem item)
        {
            try
            {
                ServiioDevice selectedDevice = null;
                String ipAddress = item.SubItems[2].Text;
                foreach (ServiioDevice device in conn.Status.Devices)
                {
                    if (device.IpAddress.Equals(ipAddress))
                        selectedDevice = device;
                }

                if (selectedDevice != null)
                {
                    if (MessageBox.Show("Are you sure you want to remove this device?", "Remove confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                        return;

                    conn.Status.Devices.Remove(selectedDevice);
                    conn.Status.Update();
                    RefreshDevices();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void StatusTabControl_Load(object sender, EventArgs e)
        {
            try
            {
                imageList32.Images.Add("GENERIC", Properties.Resources.Device);
                imageList32.Images.Add("ACTIVE", Properties.Resources.Green32);
                imageList32.Images.Add("INACTIVE", Properties.Resources.Red32);
                imageList32.Images.Add("UNKNOWN", Properties.Resources.White32);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            try
            {
                DeviceDetailsForm dialog = new DeviceDetailsForm();
                ServiioDevice newDevice = dialog.New(conn);
                if (newDevice != null)
                {
                    conn.Status.Devices.Add(newDevice);
                    conn.Status.Update();
                    RefreshDevices();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonEdit_Click(object sender, EventArgs e)
        {
            try
            {
                if (listViewDevices.SelectedItems.Count == 0)
                    return;

                EditItem(listViewDevices.SelectedItems[0]);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            try
            {
                if (listViewDevices.SelectedItems.Count == 0)
                    return;

                RemoveItem(listViewDevices.SelectedItems[0]);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            RefreshDevices();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            try
            {
                buttonStart.Text = "...wait...";
                this.Cursor = Cursors.WaitCursor;
                Application.DoEvents();

                if (!buttonStart.Checked)
                    conn.StartUpnpServer();
                else
                    conn.StopUpnpServer();

                RefreshDevices();
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
            finally
            {
                this.Cursor = Cursors.Arrow;
            }
        }

        private void listViewDevices_KeyPress(object sender, KeyPressEventArgs e)
        {
            try
            {
                if (listViewDevices.SelectedItems.Count == 0)
                    return;

                if (e.KeyChar == (char)Keys.Enter)
                    EditItem(listViewDevices.SelectedItems[0]);
                else if (e.KeyChar == (char)Keys.Delete)
                    RemoveItem(listViewDevices.SelectedItems[0]);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void listViewDevices_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                ListViewHitTestInfo hit = listViewDevices.HitTest(e.Location);
                if (hit.Item != null)
                {
                    EditItem(hit.Item);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void panelMain_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                GuiHelper.PanelBorder(e, panelMain);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }

        private void toolStripMain_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                GuiHelper.ToolStripBorder(e, toolStripMain);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }
    }
}
